<template>
  <!-- 
		分析 my-tabs组件的能力->希望创建一个通用的“my-tabs”组件，可以满足各个应用中的需求
		my-tabs 是一个通用的组件(轮子)
		1.可以在父组件中定制样式
		2.可以在父组件中指定数据
		3.可以在父组件中选默认选中项
	 -->
  <view class="tab-container">
    <view class="tab-box">
      <!-- scroll-with-animation：在设置滚动条位置时使用动画过渡	、scroll-left：设置横向滚动条位置	 -->
      <scroll-view id="_scroll" scroll-x class="scroll-view" scroll-with-animation :scroll-left="scrollLeft">
        <view class="scroll-content">
          <view class="tab-item-box">
            <block v-for="(item, index) in tabData" :key="index">
              <view
                :style="{ color: activeIndex === index ? defaultConfig.activeTextColor : defaultConfig.textColor }"
                :id="'_tab_' + index"
                class="tab-item"
                :class="{ 'tab-item-active': activeIndex === index }"
                @click="checkIndex(index)"
                >{{ item.label || item }}</view
              >
            </block>
          </view>
          <!-- 滑块 -->
          <view
            class="underLine"
            :style="{
              transform: `translateX(${slider.left + 'px'})`,
              width: defaultConfig.underLineWidth + 'px',
              height: defaultConfig.underLineHeight + 'px',
              color: defaultConfig.underLineColor
            }"
          ></view>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    // 1.可以在父组件中定制样式
    config: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 2.可以在父组件中指定数据
    tabData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 3.可以在父组件中选中项
    defaultIndex: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      // 内部维护的数据对象，为每个item单独维护一个slider的滑块对象
      tabList: [],
      activeIndex: -1, //转存激活项
      // 滑块
      slider: {
        // 滑块距离左侧的距离
        left: 0
      },
      scrollLeft: 0, // scrollView的横向滚动位置
      // 默认配置
      defaultConfig: {
        // 默认的字体颜色
        textColor: '#333333',
        // 高亮的字体颜色
        activeTextColor: '#f94d2a',
        // 滑块下划线的宽度
        underLineWidth: 24,
        // 滑块下划线的高度
        underLineHeight: 2,
        // 滑块下划线的颜色
        underLineColor: '#f94d2a'
      }
    }
  },
  methods: {
    // 改变激活项
    checkIndex(index) {
      this.activeIndex = index
      this.tobToIndex()
      // 发送一个通知，通知表示激活项发送变化了
      this.$emit('tabsClick', index)
    },
    // 根据当前activeIndex,计算 滑块的滚动位置
    tobToIndex() {
      // 获取到当前的 activeIndex
      const index = this.activeIndex
      // TODO:计算滑块的滚动 === this.slider.left
      // 配置 滚动条的left
      this.slider = {
        /**
         * TODO:left 怎么定义
         * tabItem的宽度、tabItem的left、slider的width
         * left = tabItem.left + (tabItem.width-slider.width)/2
         * */
        left: this.tabList[index]._slider.left
      }
      // this.scrollLeft=this.tabList[index]._slider.left // 控制点击时scroll-view也跟随slider滑动
      this.scrollLeft = this.activeIndex * this.defaultConfig.underLineWidth
    },
    /**
     * 更新计算每个tabs的left值
     * */
    updateTabWidth() {
      // tabItem的宽度、tabItem的left、为tabList中的每一个item维护一个slider对象
      let data = this.tabList
      if (data.length === 0) return
      // uniapp中拿到渲染之后的DOM
      // 获取dom的固定写法
      const query = uni.createSelectorQuery().in(this) // 表示拿到当前实例
      // 循环数据源
      data.forEach((item, index) => {
        //有多少条数据就有多少个slider
        // 获取dom 的 固定写法
        query
          .select('#_tab_' + index)
          .boundingClientRect(res => {
            // res就是拿到的dom
            // 为数据对象的每个 item 都维护一个 _slider 对象
            item._slider = {
              // 利用引用数据类型，赋值给了tabList,tabList就存储着_slider
              // left = tabItem.left + (tabItem.width-slider.width)/2
              left: res.left + (res.width - this.defaultConfig.underLineWidth) / 2
            }
            // 运算完成之后，计算一次【滑块】的位置
            if (data.length - 1 === index) {
              this.tobToIndex()
            }
          })
          .exec()
      })
    }
  },
  watch: {
    // 监听 config 定制主题
    config: {
      handler(val) {
        this.defaultConfig = { ...this.defaultConfig, ...val } // 解构赋值，有相同的就覆盖，没有就保持默认数据
      },
      immediate: true
    },
    // 监听激活项目的变化
    defaultIndex: {
      // 当 defaultIndex发生变化时，回调的方法
      handler(val) {
        this.activeIndex = val // 转存给activeIndex方便修改值
        // console.log(this.activeIndex)
      },
      immediate: true
    },
    tabData: {
      handler(val) {
        this.tabList = val
        // tabList 数据就已经和tabData同步了
        // 维护tabList中的每个item. 为DOM渲染完成之后
        // this.$nextTick() uniapp虽然支持，但是$nextTick()存在兼容性问题
        // 所以用setTimeout也可以
        setTimeout(() => {
          // 计算item的slider
          this.updateTabWidth()
        }, 0)
      },
      immediate: true
    }
  }
}
</script>

<style lang="scss" scoped>
.tab-container {
  position: sticky;
  /* #ifndef H5 */
  top: -1px;
  /* #endif */
  /* #ifdef H5 */
  top: 42px;
  /* #endif */
  z-index: 99;
  font-size: $uni-font-size-base;
  height: 45px;
  line-height: 45px;
  background-color: $uni-bg-color;
  .tab-box {
    width: 100%;
    height: 45px;
    display: flex;
    position: relative;
    .scroll-view {
      white-space: nowrap;
      width: 100%;
      height: 100%;
      box-sizing: border-box;
      .scroll-content {
        width: 100%;
        height: 100%;
        position: relative;

        .tab-item-box {
          height: 100%;
          .tab-item {
            box-sizing: border-box;
            height: 100%;
            display: inline-block;
            text-align: center;
            padding: 0 15px;
            position: relative;
            text-align: center;
            color: $uni-text-color;
            &-active {
              color: $uni-text-color-hot;
              font-weight: bold;
            }
          }
        }
        .underLine {
          height: 2px;
          width: 24px;
          background-color: $uni-text-color-hot;
          border-radius: 3px;
          transition: all 0.5s;
          position: absolute;
          bottom: 0;
        }
      }
    }
  }
}
// 隐藏滚动条
/deep/.uni-scroll-view::-webkit-scrollbar {
  display: none;
}
/deep/.uni-scroll-view {
  scrollbar-width: none;
}
</style>
